#include "stdafx.h"

namespace classifier_test
{

data_file_stream::data_file_stream()
{
	LearnScheme = false;
	HaveTime = false;
}

const record_scheme& data_file_stream::get_scheme() const
{
	return Scheme;
}

void data_file_stream::set_scheme(const record_scheme& Val)
{
	Scheme = Val;
}

bool data_file_stream::get_learn_scheme() const
{
	return LearnScheme;
}

void data_file_stream::set_learn_scheme(bool Val)
{
	LearnScheme = Val;
}

bool data_file_stream::get_have_time() const
{
	return HaveTime;
}

void data_file_stream::set_have_time(bool Val)
{
	HaveTime = Val;
}

void data_file_stream::open(const string& Filename, const string& Mode)
{
	File.reset(Filename, Mode);
	Fmt = record_scheme::get_formatter(File);
	Line = 0;
	if (LearnScheme)
		for (int I = 0; I < Scheme.size(); I++)
			if (Scheme[I].type == cont_attr)
			{
				Scheme[I].cont.lower_bound = numeric_limits<cont_value>::max();
				Scheme[I].cont.upper_bound = -numeric_limits<cont_value>::max();
			}
			else
				Scheme[I].discr.clear();
	reset_string(Buffer);
}

void data_file_stream::close()
{
	File.reset();
	Fmt.set_file(0);
	reset_string(Buffer);
}

bool data_file_stream::eof()
{
	return Fmt.eof();
}

void data_file_stream::read(stream_record& Rec)
{
	Fmt.set_reading();
	Rec.resize(Scheme.size());
	if (HaveTime) Fmt >> Rec.time << ": ";
	else Rec.time = Line;
	for (int I = 0; I < Rec.size(); I++)
	{
		if (I > 0) Fmt << ',';
		if (Scheme[I].type == cont_attr)
		{
			Fmt >> Rec[I].cont;
			if (LearnScheme)
			{
				if (Rec[I].cont < Scheme[I].cont.lower_bound)
					Scheme[I].cont.lower_bound = Rec[I].cont;
				if (Rec[I].cont > Scheme[I].cont.upper_bound)
					Scheme[I].cont.upper_bound = Rec[I].cont;
			}
		}
		else
		{
			Fmt >> Buffer;
			if (!LearnScheme) Rec[I].discr = Scheme[I].discr.find(Buffer);
			else Rec[I].discr = Scheme[I].discr.enter(Buffer);
		}
	}
	Fmt << ".\n";
	Line++;
	if (!LearnScheme && !Scheme.valid(Rec)) throw runtime_error("Record value is out of domain");
}

void data_file_stream::write(const stream_record& Rec)
{
	Fmt.set_writing();
	if (HaveTime) Fmt >> Rec.time << ": ";
	for (int I = 0; I < Rec.size(); I++)
	{
		if (I > 0) Fmt << ',';
		if (Scheme[I].type == cont_attr) Fmt >> Rec[I].cont;
		else Fmt >> Scheme[I].discr.get_value(Rec[I].discr);
	}
	Fmt << ".\n";
	Line++;
}

}
